
package com.bootx.entity;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotEmpty;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author black
 */
@Entity
public class AppCategory extends OrderedEntity<Long> {
    /**
     * 树路径分隔符
     */
    public static final String TREE_PATH_SEPARATOR = ",";

    @NotEmpty
    @Column(nullable = false,unique = true)
    private String otherId;

    /**
     * 名称
     */
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = false)
    @JsonView({TreeView.class})
    private String name;

    /**
     * 页面标题
     */
    @Length(max = 200)
    private String seoTitle;

    /**
     * 页面关键词
     */
    @Length(max = 200)
    private String seoKeywords;

    /**
     * 页面描述
     */
    @Length(max = 200)
    private String seoDescription;
    /**
     * 树路径
     */
    @Column(nullable = false)
    private String treePath;

    /**
     * 层级
     */
    @Column(nullable = false)
    private Integer grade;

    /**
     * 上级分类
     */
    @ManyToOne(fetch = FetchType.LAZY)
    private AppCategory parent;

    /**
     * 下级分类
     */
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    @OrderBy("order asc")
    @JsonView({TreeView.class})
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private Set<AppCategory> children = new HashSet<>();

	/**
	 * 商品
	 */
	@ManyToMany(mappedBy = "appCategories", fetch = FetchType.LAZY)
	private Set<App> apps = new HashSet<>();

    public AppCategory() {
    }

    public AppCategory(String otherId, String name) {
        this.otherId = otherId;
        this.name = name;
        this.children = new HashSet<>();
        this.seoDescription = name;
        this.seoKeywords = name;
        this.seoTitle = name;
    }

    /**
     * 获取名称
     *
     * @return 名称
     */
    public String getName() {
        return name;
    }

    /**
     * 设置名称
     *
     * @param name
     *            名称
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取页面标题
     *
     * @return 页面标题
     */
    public String getSeoTitle() {
        return seoTitle;
    }

    /**
     * 设置页面标题
     *
     * @param seoTitle
     *            页面标题
     */
    public void setSeoTitle(String seoTitle) {
        this.seoTitle = seoTitle;
    }

    /**
     * 获取页面关键词
     *
     * @return 页面关键词
     */
    public String getSeoKeywords() {
        return seoKeywords;
    }

    /**
     * 设置页面关键词
     *
     * @param seoKeywords
     *            页面关键词
     */
    public void setSeoKeywords(String seoKeywords) {
        this.seoKeywords = seoKeywords;
    }

    /**
     * 获取页面描述
     *
     * @return 页面描述
     */
    public String getSeoDescription() {
        return seoDescription;
    }

    /**
     * 设置页面描述
     *
     * @param seoDescription
     *            页面描述
     */
    public void setSeoDescription(String seoDescription) {
        this.seoDescription = seoDescription;
    }

    /**
     * 获取树路径
     *
     * @return 树路径
     */
    public String getTreePath() {
        return treePath;
    }

    /**
     * 设置树路径
     *
     * @param treePath
     *            树路径
     */
    public void setTreePath(String treePath) {
        this.treePath = treePath;
    }

    /**
     * 获取层级
     *
     * @return 层级
     */
    public Integer getGrade() {
        return grade;
    }

    /**
     * 设置层级
     *
     * @param grade
     *            层级
     */
    public void setGrade(Integer grade) {
        this.grade = grade;
    }

    /**
     * 获取上级分类
     *
     * @return 上级分类
     */
    public AppCategory getParent() {
        return parent;
    }

    /**
     * 设置上级分类
     *
     * @param parent
     *            上级分类
     */
    public void setParent(AppCategory parent) {
        this.parent = parent;
    }

    /**
     * 获取下级分类
     *
     * @return 下级分类
     */
    public Set<AppCategory> getChildren() {
        return children;
    }

    /**
     * 设置下级分类
     *
     * @param children
     *            下级分类
     */
    public void setChildren(Set<AppCategory> children) {
        this.children = children;
    }

    public Set<App> getApps() {
        return apps;
    }

    public void setApps(Set<App> apps) {
        this.apps = apps;
    }

    public String getOtherId() {
        return otherId;
    }

    public void setOtherId(String otherId) {
        this.otherId = otherId;
    }

    /**
     * 获取所有上级分类ID
     *
     * @return 所有上级分类ID
     */
    @Transient
    @JsonView({TreeView.class})
    public Long[] getParentIds() {
        String[] parentIds = StringUtils.split(getTreePath(), TREE_PATH_SEPARATOR);
        Long[] result = new Long[parentIds.length];
        for (int i = 0; i < parentIds.length; i++) {
            result[i] = Long.valueOf(parentIds[i]);
        }
        return result;
    }

    /**
     * 获取所有上级分类
     *
     * @return 所有上级分类
     */
    @Transient
    public List<AppCategory> getParents() {
        List<AppCategory> parents = new ArrayList<>();
        recursiveParents(parents, this);
        return parents;
    }

    /**
     * 递归上级分类
     *
     * @param parents
     *            上级分类
     * @param productCategory
     *            商品分类
     */
    private void recursiveParents(List<AppCategory> parents, AppCategory productCategory) {
        if (productCategory == null) {
            return;
        }
        AppCategory parent = productCategory.getParent();
        if (parent != null) {
            parents.add(0, parent);
            recursiveParents(parents, parent);
        }
    }
}